(function(window) {
  function MyPromise(excutor) {
    this.PromiseState = 'pending' // 记录promise对象的状态
    this.PromiseResult = undefined // 记录promise对象的成功/失败值
    this.PromiseCallbacks = [] // 记录promise对象先指定回调后改变状态时的回调函数，格式为{onResolved:xxx,onRejected:xxx}

    const self = this

    function resolve(value) {
      if (self.PromiseState !== 'pending') return // promise对象的状态只能修改一次
      self.PromiseState = 'fulfilled'
      self.PromiseResult = value

      // 先指定回调后改变状态，修改完状态后就来执行相关的回调
      self.PromiseCallbacks.forEach(callback => {
        setTimeout(function() {
          callback.onResolved()
        })
      })
    }

    function reject(reason) {
      if (self.PromiseState !== 'pending') return // promise对象的状态只能修改一次
      self.PromiseState = 'rejected'
      self.PromiseResult = reason

      // 先指定回调后改变状态，修改完状态后就来执行相关的回调

      self.PromiseCallbacks.forEach(callback => {
        setTimeout(function() {
          callback.onRejected()
        })
      })
    }

    try {
      excutor(resolve, reject)
    } catch (e) {
      reject(e)
    }
  }

  MyPromise.prototype.then = function(onResolved, onRejected) {
    let self = this

    // 值传递
    if (typeof onResolved !== 'function') onResolved = value => value

    // 异常穿透
    if (typeof onRejected !== 'function') onRejected = reason => reason
    return new MyPromise((resolve, reject) => {
      function callback(type) {
        try {
          let resolveReturn = type(self.PromiseResult) // 记录then中第一个回调的返回值
            // 1. 返回值为MyPromise对象(根据该对象状态修改返回Promise对象的状态)
          if (resolveReturn instanceof MyPromise) {
            resolveReturn.then(resolve, reject)
          } else {
            // 2. 返回值为普通值（包装为Promise成功状态）
            resolve(resolveReturn)
          }
        } catch (e) {
          // 3.回调函数中出现错误，返回拒绝的Promise
          reject(e)
        }
      }

      // 先指定状态后调用回调
      if (this.PromiseState === 'fulfilled') {
        setTimeout(function() {
          callback(onResolved)
        })
      } else if (this.PromiseState === 'rejected') {
        setTimeout(function() {
          callback(onRejected)
        })
      } else if (this.PromiseState === 'pending') {
        this.PromiseCallbacks.push({
          onResolved() {
            callback(onResolved)
          },
          onRejected() {
            callback(onRejected)
          }
        })
      }
    })
  }

  MyPromise.prototype.catch = function(onRejected) {
    return this.then(undefined, onRejected)
  }

  MyPromise.resolve = function(value) {
    return new MyPromise((resolve, reject) => {
      if (value instanceof MyPromise) {
        value.then(resolve, reject)
      } else {
        resolve(value)
      }
    })
  }

  MyPromise.reject = function(reason) {
    return new MyPromise((undefined, reject) => {
      reject(reason)
    })
  }

  MyPromise.all = function(promises) {
    return new MyPromise((resolve, reject) => {
      let fulfilledCount = 0 // 记录状态为fulfilled的promise对象的梳理
      let fulfilledResults = [] // 记录成功值
      promises.forEach((promise, index) => {
        promise.then(value => {
          fulfilledResults[index] = value
          if (++fulfilledCount === promises.length) {
            resolve(fulfilledResults)
          }
        }, reason => {
          reject(reason)
        })
      })
    })
  }

  MyPromise.race = function(promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(resolve, reject)
      })
    })
  }

  MyPromise.resolveDelay = function(value, time) {
    return new MyPromise((resolve, reject) => {
      setTimeout(function() {
        if (value instanceof MyPromise) {
          value(resolve, reject)
        } else {
          resolve(value)
        }
      })
    }, time)
  }

  MyPromise.rejectDelay = function(reason, time) {
    return new MyPromise((undefined, reject) => {
      setTimeout(function() {
        reject(reason)
      }, time)
    })
  }

  window.MyPromise = MyPromise
})(window)

// class MyPromise {
//   constructor(excutor) {
//     this.PromiseState = 'pending' // 记录promise对象的状态
//     this.PromiseResult = undefined // 记录promise对象的成功/失败值
//     this.PromiseCallbacks = [] // 记录promise对象先指定回调后改变状态时的回调函数，格式为{onResolved:xxx,onRejected:xxx}

//     const self = this

//     function resolve(value) {
//       if (self.PromiseState !== 'pending') return // promise对象的状态只能修改一次
//       self.PromiseState = 'fulfilled'
//       self.PromiseResult = value

//       // 先指定回调后改变状态，修改完状态后就来执行相关的回调
//       self.PromiseCallbacks.forEach(callback => {
//         setTimeout(function() {
//           callback.onResolved()
//         })
//       })
//     }

//     function reject(reason) {
//       if (self.PromiseState !== 'pending') return // promise对象的状态只能修改一次
//       self.PromiseState = 'rejected'
//       self.PromiseResult = reason

//       // 先指定回调后改变状态，修改完状态后就来执行相关的回调
//       self.PromiseCallbacks.forEach(callback => {
//         setTimeout(function() {
//           callback.onRejected()
//         })
//       })
//     }

//     try {
//       excutor(resolve, reject)
//     } catch (e) {
//       reject(e)
//     }
//   }

//   then(onResolved, onRejected) {
//     let self = this

//     // 值传递
//     if (typeof onResolved !== 'function') onResolved = value => value

//     // 异常穿透
//     if (typeof onRejected !== 'function') onRejected = reason => reason
//     return new MyPromise((resolve, reject) => {
//       function callback(type) {
//         try {
//           let resolveReturn = type(self.PromiseResult) // 记录then中第一个回调的返回值
//             // 1. 返回值为MyPromise对象(根据该对象状态修改返回Promise对象的状态)
//           if (resolveReturn instanceof MyPromise) {
//             resolveReturn.then(resolve, reject)
//           } else {
//             // 2. 返回值为普通值（包装为Promise成功状态）
//             resolve(resolveReturn)
//           }
//         } catch (e) {
//           // 3.回调函数中出现错误，返回拒绝的Promise
//           reject(e)
//         }
//       }

//       // 先指定状态后调用回调
//       if (this.PromiseState === 'fulfilled') {
//         setTimeout(function() {
//           callback(onResolved)
//         })
//       } else if (this.PromiseState === 'rejected') {
//         setTimeout(function() {
//           callback(onRejected)
//         })
//       } else if (this.PromiseState === 'pending') {
//         this.PromiseCallbacks.push({
//           onResolved() {
//             callback(onResolved)
//           },
//           onRejected() {
//             callback(onRejected)
//           }
//         })
//       }
//     })
//   }

//   catch (onRejected) {
//     return this.then(undefined, onRejected)
//   }

//   static resolve(value) {
//     return new MyPromise((resolve, reject) => {
//       if (value instanceof MyPromise) {
//         value.then(resolve, reject)
//       } else {
//         resolve(value)
//       }
//     })
//   }

//   static reject(reason) {
//     return new MyPromise((undefined, reject) => {
//       reject(reason)
//     })
//   }

//   static resolveDelay(value, time) {
//     return new MyPromise((resolve, reject) => {
//       setTimeout(function() {
//         if (value instanceof MyPromise) {
//           value(resolve, reject)
//         } else {
//           resolve(value)
//         }
//       })
//     }, time)
//   }

//   static rejectDelay(reason, time) {
//     return new MyPromise((undefined, reject) => {
//       setTimeout(function() {
//         reject(reason)
//       }, time)
//     })
//   }

//   static all(promises) {
//     return new MyPromise((resolve, reject) => {
//       let fulfilledCount = 0 // 记录状态为fulfilled的promise对象的梳理
//       let fulfilledResults = [] // 记录成功值
//       promises.forEach((promise, index) => {
//         promise.then(value => {
//           fulfilledResults[index] = value
//           if (++fulfilledCount === promises.length) {
//             resolve(fulfilledResults)
//           }
//         }, reason => {
//           reject(reason)
//         })
//       })
//     })
//   }

//   static race(promises) {
//     return new MyPromise((resolve, reject) => {
//       promises.forEach(promise => {
//         promise.then(resolve, reject)
//       })
//     })
//   }
// }